<template>
  <el-form label-width="100px">
    <!-- 文本框 -->
    <el-form-item label="修改SPU名称">
      <el-input
        placeholder="请输入SPU名称"
        style="width: 80%"
        v-model="SpuParams.spuName"
      ></el-input>
    </el-form-item>
    <!-- 下拉框 -->
    <el-form-item label="SPU品牌">
      <el-select v-model="SpuParams.tmId">
        <el-option
          :label="row.tmName"
          v-for="row in AllTradeMark"
          :key="row.id"
          :value="row.id"
        ></el-option>
      </el-select>
    </el-form-item>
    <!-- 文本区域 -->
    <el-form-item label="SPU描述">
      <el-input
        type="textarea"
        placeholder="请输入SPU描述"
        v-model="SpuParams.description"
      ></el-input>
    </el-form-item>
    <!-- 图标 -->
    <el-form-item label="SPU图标" prop="logoUrl">
      <!--                                                      上传图片的接口地址 -->
      <el-upload
        v-model:file-list="ImageList"
        action="/api/admin/product/fileUpload"
        list-type="picture-card"
        :on-preview="handlePictureCardPreview"
        :on-remove="handleRemove"
        :before-upload="handleUpload"
      >
        <el-icon>
          <Plus />
        </el-icon>
      </el-upload>
      <!--                  是否放大 -->
      <el-dialog v-model="dialogVisible">
        <!--             放大图片的地址 -->
        <img w-full :src="dialogImageUrl" alt="Preview Image" />
      </el-dialog>
    </el-form-item>
    <!-- 表单 -->
    <el-form-item label="SPU销售属性">
      <el-select
        @change="$forceUpdate()"
        :placeholder="RemainsArr.length ? `还有${RemainsArr.length}项未添加` : `已添加所有属性`"
      >
        <!--                                                                                                                      要加value属性，否则会出bug -->
        <el-option
          :label="row.name"
          v-for="row in RemainsArr"
          :key="row.name"
          @click="handleAddAttr(row.name, row.id)"
          :value="row.name"
        ></el-option>
      </el-select>
      <!-- <el-button style="margin-left: 10px" type="primary" size="default" icon="Plus">
        添加属性值
      </el-button> -->
      <el-table border style="margin: 10px 0px" :data="AttrList">
        <el-table-column label="序号" type="index" align="center" width="80px"></el-table-column>
        <el-table-column label="销售属性名字" width="120px" prop="saleAttrName"></el-table-column>
        <el-table-column label="销售属性值">
          <!-- eslint-disable -->
          <template #="{ row, $index }">
            <span v-for="(item, index) in row.spuSaleAttrValueList" :key="index">
              <!--                            点击x图标时，删除当前tag -->
              <el-tag
                v-show="!item.isShow"
                @close="row.spuSaleAttrValueList.splice(index, 1)"
                class="mx-1"
                closable
                style="margin: 0px 10px"
              >
                {{ item.saleAttrValueName }}
              </el-tag>
            </span>
            <el-input
              v-show="row.isShow"
              v-model="row.saleAttrValue"
              style="width: 100px"
              @blur="handleBlur(row)"
            ></el-input>
            <el-button
              v-show="!row.isShow"
              type="primary"
              size="small"
              icon="Plus"
              @click="handlePlus(row)"
            ></el-button>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="120px">
          <template #="{ row, $index }">
            <el-button
              type="primary"
              size="small"
              icon="Delete"
              @click="AttrList.splice($index, 1)"
            ></el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-form-item>
    <!-- 保存与取消按钮 -->
    <el-form-item>
      <el-button type="primary" size="default" @click="save">保存</el-button>
      <el-button type="primary" size="default" @click="cancel">取消</el-button>
    </el-form-item>
  </el-form>
</template>

<script setup lang="ts">
//引入ElMessage
import { ElMessage } from 'element-plus'
//引入ref
import { ref, computed } from 'vue'
//引入ts数据类型
import {
  SpuData,
  TradeMark,
  SpuImage,
  SaleAttr,
  HasSaleAttr,
  SpuAttrValue,
} from '@/api/product/spu/type'
//引入获取数据的接口
import {
  reqAllTrademark,
  reqImageList,
  reqAttrList,
  reqAllSaleAttr,
  reqAddOrUpdateSpu,
} from '@/api/product/spu/index'

//从父组件传scene
let $emit = defineEmits(['changeScene'])

//保存从row中获取的数据
//全部的品牌数据(下拉框的可选项)
let AllTradeMark = ref<TradeMark[]>([])
//已有的图片数据
let ImageList = ref<SpuImage[]>([])
//已有的属性值
let AttrList = ref<SaleAttr[]>([])
//全部的属性值(下拉框的可选项)
let AllAttr = ref<HasSaleAttr[]>([])
//控制是否放大显示图片
let dialogVisible = ref<boolean>(false)
//存储预览图的url
let dialogImageUrl = ref<string>()
//收集当前SPU的全部属性值
let SpuParams = ref<SpuData>({
  category3Id: '', //收集的三级分类ID
  description: '', //SPU的名字
  spuName: '', //SPU的描述
  tmId: '', //品牌ID
  spuImageList: [],
  spuSaleAttrList: [],
})

//计算属性计算出当前SPU还剩下没添加的属性
let RemainsArr = computed(() => {
  return AllAttr.value.filter((item) => {
    //every可以遍历数组AttrList，寻找是否有item.name在AttrList中不存在，如果有就返回true，返回的项被filter选择
    return AttrList.value.every((item1) => {
      return item1.saleAttrName != item.name
    })
  })
})

//点击取消按钮，将值0传到父组件的scene中
const cancel = () => {
  $emit('changeScene', { value: 0, params: '' })
}
//父组件传值给spuForm调用接口方法,修改Spu
const initHasSpuData = async (row: SpuData) => {
  //获取数据
  let result1 = await reqAllTrademark()
  let result2 = await reqImageList(row.id)
  let result3 = await reqAttrList(row.id)
  let result4 = await reqAllSaleAttr()
  if (
    result1.code === 200 &&
    result2.code === 200 &&
    result3.code === 200 &&
    result4.code === 200
  ) {
    //直接赋值
    SpuParams.value = row
    AllTradeMark.value = result1.data
    ImageList.value = result2.data.map((item) => {
      return {
        name: item.imgName,
        url: item.imgUrl,
      }
    }) //使用map统一ImageList的属性
    AttrList.value = result3.data
    AllAttr.value = result4.data
  } else {
    ElMessage({
      type: 'error',
      message: '获取信息失败',
    })
    $emit('changeScene', 0)
  }
}
//点击预览图片时的钩子
//                               钩子自带的参数,当前预览图片的地址
const handlePictureCardPreview = (file: any) => {
  //点击预览时，dialogVisible变为true
  dialogVisible.value = true
  dialogImageUrl = file.url
}
//删除图片时的钩子(不用写内容)
const handleRemove = () => {}
//图片上传成功前的钩子
const handleUpload = (file: any) => {
  if (file.type === 'image/png' || file.type == 'image/jpeg' || file.type === 'image/gif') {
    if (file.size / 1024 / 1024 < 4) {
      return true
    } else {
      ElMessage({
        type: 'error',
        message: '上传文件大小应小于4M',
      })
      return false
    }
  } else {
    //element-plus中的提示组件
    ElMessage({
      type: 'error',
      message: '文件格式应改为PNG|JPG|GIF',
    })
    return false
  }
}
//下拉框点击事件的回调，将点击的属性加到AttrList中
const handleAddAttr = (name: string, id: number) => {
  AttrList.value.push({
    saleAttrName: name,
    baseSaleAttrId: id,
    spuSaleAttrValueList: [],
  })
}
//添加新的tag的回调，由+按钮变为文本框
const handlePlus = (row: SaleAttr) => {
  row.isShow = true
  row.saleAttrValue = ''
}
//由文本框变为+按钮的回调
const handleBlur = (row: SaleAttr) => {
  //判断标签不为空
  if (!row.saleAttrValue) {
    ElMessage({
      type: 'error',
      message: '标签内容不能为空',
    })
    row.isShow = false
    return
  }
  //判断标签不重复
  if (
    !row.spuSaleAttrValueList.every((item) => {
      return item.saleAttrValueName != row.saleAttrValue
    })
  ) {
    ElMessage({
      type: 'error',
      message: '标签内容不能重复',
    })
    row.isShow = false
    return
  }
  //从row中取出下面两个属性，组成一个SpuAttrValue类型数据
  const { saleAttrValue, baseSaleAttrId } = row
  let newSaleAttrValue: SpuAttrValue = {
    baseSaleAttrId,
    saleAttrValueName: saleAttrValue,
  }
  //将组成的数据push到标签数组中
  row.spuSaleAttrValueList.push(newSaleAttrValue)
  //隐藏文本框，显示标签
  row.isShow = false
}
//保存按钮的回调
const save = async () => {
  //整理数据
  //之前保存照片数据时改变了数据名，保存时改回来
  SpuParams.value.spuImageList = ImageList.value.map((item: any) => {
    return {
      imgName: item.name,
      imgUrl: (item.response && item.response.data) || item.url,
    }
  })
  SpuParams.value.spuSaleAttrList = AttrList.value

  let result = await reqAddOrUpdateSpu(SpuParams.value)
  if (result.code === 200) {
    ElMessage({
      type: 'success',
      message: SpuParams.value.id ? '更新成功' : '添加成功',
    })
    $emit('changeScene', {
      value: 0,
      params: SpuParams.value.id ? 'Update' : 'Add',
    })
  } else {
    ElMessage({
      type: 'error',
      message: SpuParams.value.id ? '更新失败' : '添加失败',
    })
  }
}
//父组件传值给SpuForm的接口方法，添加Spu
const initAddSpuData = async (c3Id: number) => {
  //获取数据前先清空当前数据
  //清空SpuParams
  Object.assign(SpuParams.value, {
    category3Id: '', //收集的三级分类ID
    description: '', //SPU的名字
    spuName: '', //SPU的描述
    tmId: '', //品牌ID
    spuImageList: [],
    spuSaleAttrList: [],
  })
  //清空照片和已选属性
  ImageList.value = []
  AttrList.value = []
  //清空剩下未选的属性

  //调用接口获取数据
  let result1 = await reqAllTrademark()
  let result2 = await reqAllSaleAttr()
  if (result1.code === 200 && result2.code === 200) {
    SpuParams.value.category3Id = c3Id
    AllTradeMark.value = result1.data
    AllAttr.value = result2.data
  } else {
    ElMessage({
      type: 'error',
      message: '获取信息失败',
    })
    $emit('changeScene', { value: 0, params: 'Add' })
  }
}
defineExpose({ initHasSpuData, initAddSpuData })
</script>

<style scoped>
.avatar-uploader .avatar {
  width: 178px;
  height: 178px;
  display: block;
}
</style>

<style>
.avatar-uploader .el-upload {
  border: 1px dashed var(--el-border-color);
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: var(--el-transition-duration-fast);
}

.avatar-uploader .el-upload:hover {
  border-color: var(--el-color-primary);
}

.el-icon.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 178px;
  height: 178px;
  text-align: center;
}
</style>
